/*
 * Simple Extensible Format.
 * 
 * API.
 */
package java.org.thotheolh.sef.api;

import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;

/**
 *
 * @author Thotheolh
 */
public class SEFReader {

    private boolean strict = false;
    private ArrayList<Character> tempCharList;
    private HashMap<String, String> metadataMap;
    private boolean PARSE_META_FLAG = true;

    public SEFReader() {
        setStrict(false);
        init();
    }

    public SEFReader(boolean mode) {
        setStrict(mode);
        init();
    }

    private void init() {
        this.tempCharList = new ArrayList<>();
        this.setMetadataMap(new HashMap<String, String>());
    }

    ////////////////////////////////////////////////
    //---------User Callable Method Region--------//
    ////////////////////////////////////////////////
    
    /**
     * Reading in characters with a supplied Reader.
     * 
     * Steps on how the Reader works:
     * 1.   Reads in each character.
     * 2.   Parses the character for SEF syntax.
     * 3.   Checks if the assembled characters in the char list makes up any metadata unless 'PARSE_META_FLAG' is disabled.
     * 4.   If there is metadata, they will be stored in the metadata hashmap.
     * 
     * @param reader
     * @throws IOException
     */
    public void read(Reader reader) throws IOException {
        int inputChar;
        while ((inputChar = reader.read()) != -1) {
            char c = (char) inputChar;
            parse(c);
            handleMeta();
        }
    }

    ////////////////////////////////////////////////
    //------------Internal Method Region----------//
    ////////////////////////////////////////////////
    
    /**
     * Parses an input character and decides the action to take. Parsed input characters would be collected in the char list.
     *
     * @param c
     */
    private void parse(char c) {
        switch (c) {
            
            // Element or Group delimiter.
            case ';':
                break;
            
            // Kery-Value delimiter.
            case ':':
                break;
            
            // Key-Value delimiter.
            case '=':
                break;
            
            // Escape character '\'.
            case '\\':
                break;
            
            // Group / Array opening.
            case '[':
                break;
            
            // Group / Array closing.
            case ']':
                break;
            
            // Element / Group seperating delimiter. 
            // E.g. 'hello','world' ---> 2 elements.
            case ',':
                break;
            
            // Comment delimiter.    
            // E.g. '/ This is a comment /' for commenting in a limited fashion. 
            // E.g. '/ This are all commented text' for commenting everything after the first '/'.
            case '/':
                break;
                
        }
    }
    
    /**
     * Handles metadata tags.
     * 
     * Reads the tempCharList for any metadata tags to be handled.
     */
    private void handleMeta() {
        
    }
    
    /**
     * Checks if a character is a Base64 permissible character.
     * 
     * @param c
     * @return 
     */
    private boolean isBase64Char(char c) {
        String base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890+/";
        return base64.contains("" + c);
    }

    ////////////////////////////////////////////////
    //----------Getters and Setters Region--------//
    ////////////////////////////////////////////////
    
    /**
     * @return the strict
     */
    public boolean isStrict() {
        return strict;
    }

    /**
     * @param strict the strict to set
     */
    public void setStrict(boolean strict) {
        this.strict = strict;
    }

    /**
     * @return the metadataMap
     */
    public HashMap<String, String> getMetadataMap() {
        return metadataMap;
    }

    /**
     * @param metadataMap the metadataMap to set
     */
    public void setMetadataMap(HashMap<String, String> metadataMap) {
        this.metadataMap = metadataMap;
    }
}
